package com.avo.ramcache.orm.impl;

import com.avo.ramcache.config.IEntity;
import com.avo.ramcache.orm.impl.m2s.ServerHibernateTemplate;
import com.avo.ramcache.orm.Accessor;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import java.io.Serializable;

@SuppressWarnings({"unchecked"})
public class HibernateAccessor extends HibernateDaoSupport implements Accessor {

    public HibernateAccessor() {
    }

    public HibernateAccessor(SessionFactory sessionFactory) {
        super();
        setSessionFactory(sessionFactory);
    }


    @Override
    public <PK extends Serializable, T extends IEntity<?>> T load(Class<T> clz, PK id) {
        return getHibernateTemplate().get(clz, id);
    }

    @Override
    public <PK extends Serializable, T extends IEntity<?>> PK save(Class<T> clz, T entity) {
        return (PK) getHibernateTemplate().save(entity);
    }

    @Override
    public <PK extends Serializable, T extends IEntity<?>> void remove(Class<T> clz, PK id) {
        T entity = load(clz, id);
        if (entity == null) {
            return;
        }
        getHibernateTemplate().delete(entity);
    }

    @Override
    public <PK extends Serializable, T extends IEntity<?>> void update(Class<T> clz, T entity) {
        getHibernateTemplate().update(entity);
    }

    @Override
    public <PK extends Serializable, T extends IEntity<?>> void saveOrUpdate(Class<T> clz, T entity) {
        try {
            getHibernateTemplate().saveOrUpdate(entity);
        } catch (DataAccessException e) {
            e.printStackTrace();
            throw e;
        }
    }

    @Override
    protected HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) {
        return new ServerHibernateTemplate(sessionFactory);
    }
}
